Das Hooksche Gesetz verknüpft Dehnung
Die Lamé-Parameter
In Python:
from skfem.models.elasticity import lame_parameters
lam, mu = lame_parameters(E=210e3, nu=0.3) # Stahl, Einheiten MPa + mm
An jedem Gitterknoten gibt es 3 Freiheitsgrade (DOFs): Verschiebung in x, y, z.
Randbedingungen legen fest, was bekannt ist:
| Fläche | Bedingung | Bedeutung |
|---|---|---|
| Unterseite |
fest eingespannt | |
| Oberseite |
Kraft |
Zugbelastung |
| Rest | – | gesucht |
Ohne Randbedingungen ist das Gleichungssystem singulär – der Körper könnte sich beliebig verschieben.
Physical Groups aus cadgmsh werden direkt als benannte Ränder übernommen:
f = basis.zeros() # Lastvektor: 1 Eintrag pro DOF, initial 0
# Unterseite: alle 3 DOFs pro Knoten fixieren (x, y, z)
fixed = basis.get_dofs(skfem_mesh.boundaries["bottom"]).all()
# Oberseite: nur z-DOFs – Kraft in z-Richtung aufprägen
top = basis.get_dofs(skfem_mesh.boundaries["top"]).nodal["u^3"]
f[top] = 1000.0 / len(top) # 1000 N gleichmäßig verteilt
Kein Koordinatenfilter, keine Gleitkomma-Toleranz – die Geometrie ist bereits bekannt.
Aus dem Spannungstensor
Zylinder
Analytische Lösung:
Plausibilitätscheck:
import cadgmsh, build123d as bd
from skfem.io.meshio import from_meshio
# Gitter erzeugen mit benannten Rändern
part = bd.Cylinder(radius=10, height=40)
cadmesh = cadgmsh.mesh(part, dim=3, lc=4, physical={
"top": part.faces().sort_by(bd.Axis.Z).last,
"bottom": part.faces().sort_by(bd.Axis.Z).first,
})
skfem_mesh = from_meshio(cadmesh)
# Steifigkeitsmatrix (Stahl: E=210 GPa, ν=0.3)
lam, mu = lame_parameters(E=210e3, nu=0.3)
basis = Basis(skfem_mesh, ElementVector(ElementTetP1()))
K = linear_elasticity(lam, mu).assemble(basis)
# Lastvektor + Randbedingungen
f = basis.zeros()
top_dofs = basis.get_dofs(skfem_mesh.boundaries["top"]).nodal["u^3"]
f[top_dofs] = 1000.0 / len(top_dofs)
fixed_dofs = basis.get_dofs(skfem_mesh.boundaries["bottom"]).all()
# Lösen
u = solve(*condense(K, f, D=fixed_dofs))
PyVista unterscheidet zwei Arten von Ergebnisdaten:
# Knotenbasiert – 1 Wert pro Knoten (z.B. Verschiebung)
grid.point_data["Verschiebung z [mm]"] = u[basis.nodal_dofs[2]]
# Elementbasiert – 1 Wert pro Tetraeder (z.B. Spannung)
grid.cell_data["Von-Mises [MPa]"] = vm
Danach wie gewohnt: grid.plot(scalars="...") oder pv.Plotter für mehrere Ansichten.
Vollständiger Code (inkl. Grid-Konvertierung):
fem_zug_zylinder.py
Diese Einheit behandelt den einfachsten Fall: statisch, linear, isotropes Material.
Nicht abgedeckt:
| Phänomen | Erweiterung |
|---|---|
| Große Verformungen | Nichtlineare Geometrie |
| Plastizität, Bruch | Nichtlineares Material |
| Kontakt, Reibung | Kontaktmechanik |
| Schwingungen, Stoß | Dynamik / Modalanalyse |
| Wärme, Strömung | Multiphysik |
| Dünnwandige Strukturen | Schalenelemente |
Für reale Bauteile ist die Wahl des richtigen Modells mindestens so wichtig wie die Berechnung selbst.
Führen Sie fem_zug_zylinder.py aus und überprüfen Sie:
Variationen:
-clmax 2.0) – ändert sich das Ergebnis?